# -*- coding: utf-8 -*-
"""
Created on Wed Nov 14 22:12:57 2012

@author: Maxim
"""
import numpy as ny
from math import sin, cos, radians, degrees, acos, asin
import win32com.client
from Shapes import *

class WingPartDesigner():
    def __init__(self,zeroPt=[0,0,0]):
        zeroPt = [float(crd) for crd in zeroPt]
        self.catia = win32com.client.Dispatch('catia.application')
        partDocument1 = self.catia.Documents.Add("Part")
        partDocument1 = self.catia.ActiveDocument
        self.part = partDocument1.Part
        self.hSF = self.part.HybridShapeFactory
        self.hBodies = self.part.HybridBodies
        self.hBody = self.hBodies.Item("Geometrical Set.1")
        zeroPt = self.hSF.AddNewPointCoord(zeroPt[0],zeroPt[1],zeroPt[2])
        self.refZero = self.part.CreateReferenceFromObject(zeroPt)

    def create_airfoil(self, af, axis=0.25, angle=0, position=0):
        plane = af.plane

        if af.createRadius:
            originElements = self.part.OriginElements
            centerPt = self.hSF.AddNewPointCoord(af.Rcenter[0],af.Rcenter[1],af.Rcenter[2])
            if plane=='xz':
                workPlane = originElements.PlaneZX
            elif plane=='xy':
                workPlane = originElements.PlaneXY
            refCenter = self.part.CreateReferenceFromObject(centerPt)
            refPlane  = self.part.CreateReferenceFromObject(workPlane)
            leCircle  = self.hSF.AddNewCircleCtrRad(refCenter, refPlane, False, af.R)
            leCircle.SetLimitation(1)
            refLeCircle = self.part.CreateReferenceFromObject(leCircle)
        else:
            refLeCircle = False

        def create_point(coord,append=False):
            point = self.hSF.AddNewPointCoord(coord[0],coord[1],coord[2])
            refPt = self.part.CreateReferenceFromObject(point)
            if append:
                self.hBody.AppendHybridShape(point)
            return refPt
        
        def create_spline(coord,refLeCircle,direction=1):
            spline = self.hSF.AddNewSpline()
            spline.SetSplineType(0)
            spline.SetClosing(0)
            refLePt = create_point(coord[0])
            if refLeCircle==False:
                spline.AddPointWithConstraintExplicit(refLePt,None, -1, 1, None, 0)
            else:
                spline.AddPointWithConstraintFromCurve(refLePt,refLeCircle,1.0,direction,2)
            
            for point in coord[1:]:
                reference = create_point(point)
                spline.AddPointWithConstraintExplicit(reference, None, -1, 1, None, 0)
            refTePt = reference
            refSpline = self.part.CreateReferenceFromObject(spline)
            return refLePt, refTePt, refSpline
        
        def create_rotate(reference,axisPt,direction,angle,append=False):
            refAxisPtOrig = create_point(axisPt)
            axisDir = self.hSF.AddNewDirectionByCoord(direction[0],direction[1],direction[2])
            axisLine = self.hSF.AddNewLinePtDir(refAxisPtOrig,axisDir,0.,13.,False)
            refAxisLine = self.part.CreateReferenceFromObject(axisLine)
            rotate = list()
            for ref in reference:
                rotateObj = self.hSF.AddNewEmptyRotate()
                rotateObj.ElemToRotate = ref
                rotateObj.Axis = refAxisLine
                rotateObj.AngleValue = float(angle)
                rotate.append(self.part.CreateReferenceFromObject(rotateObj))
                if append:
                    self.hBody.AppendHybridShape(rotateObj)
            return rotate
        
        def create_translate(reference,distance,append=False):
            translate = list()
            secondPt = create_point(distance)
            for ref in reference:
                transObj = self.hSF.AddNewEmptyTranslate()
                transObj.ElemToTranslate = ref
                transObj.VectorType = 1
                transObj.FirstPoint = self.refZero
                transObj.SecondPoint = secondPt
                translate.append(self.part.CreateReferenceFromObject(transObj))
                if append:
                    self.hBody.AppendHybridShape(transObj)
            return translate

        refLePt1, refTePt1, refSpline1 = create_spline(af.up,refLeCircle,1)
        refLePt2, refTePt2, refSpline2 = create_spline(af.lo,refLeCircle,-1)

        afSection = self.hSF.AddNewJoin(refSpline1, refSpline2)
        self.part.update()
        self.part.update()
        
        refAfSection = self.part.CreateReferenceFromObject(afSection)
        fullSection = [refAfSection,refTePt1,refLePt1,refTePt2]
        
        axisPt = [af.chord*axis,0.0,0.0]
        direction = [0,1,0.0]
        refRotate = create_rotate(fullSection,axisPt,direction,angle,True)
        #refTranslate = create_translate(refRotate,[0.0,0.0,0.0])
        self.part.update()
        self.part.update()

        """
        airfoil with chord = 1m
        rotate for given incidence angle
        scale to get chord
        translate to set span, dihedral etc
        use leading edge, trailing edge points
        return translate, as an object
        """

class Af():
    def __init__(self):
        self.createRadius = False
        self.Rcenter = [20,0.0,0.0]
        self.R = 20
        self.up = ny.array([[0.0, 0.0, 0.0],[25,0,25],[75,0,0]])
        self.lo = ny.array([[0.0, 0.0, 0.0],[25,0,-25],[75,0,0]])

def run_test():
    path = 'NACA0012.txt'
    af = load_airfoil_txt(path)
    #af.set_le_radius(1.5867e-2,0.0)
    af.set_chord(1500)
    af.set_te_gap(15.0)
    af.set_plane('xz')
    pd = WingPartDesigner()
    pd.create_airfoil(af,angle=0)

if __name__=="__main__":
    run_test()

class BodyPartDesigner():
    pass

